package cn.dduan.fool.lock.sync;

/**
 * synchronized
 * <p>
 * 使用范围：方法、代码块
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/6
 */
public class MySynchronized {

    /**
     * 同步普通方法 = synchronized(this)
     *
     * @param
     * @return void
     * @author dduan
     * @version 1.0
     * @date 2023/4/6
     */
    public synchronized void synchronizedFun() {
        print("同步普通方法");
    }

    /**
     * 同步静态方法 = synchronized(MySynchronized.class)
     *
     * @param
     * @return void
     * @author dduan
     * @version 1.0
     * @date 2023/4/6
     */
    public static synchronized void synchronizedStaticFun() {
        for (int i = 0; i < 3; i++) {
            try {
                System.out.println(Thread.currentThread().getName() + "-同步静态方法");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 同步代码块1 = synchronized(MySynchronized.class)
     * 作用对象为：类
     *
     * @param
     * @return void
     * @author dduan
     * @version 1.0
     * @date 2023/4/6
     */
    public void synchronizedCodelockClass() {
        synchronized (MySynchronized.class) {
            print("同步代码块1");
        }
    }

    /**
     * 同步代码块2 = synchronized(this)
     * 作用对象为：对象
     *
     * @param
     * @return void
     * @author dduan
     * @version 1.0
     * @date 2023/4/6
     */
    public void synchronizedCodelockObjct() {
        synchronized (this) {
            print("同步代码块2");
        }
    }

    private void print(String name) {
        String tName = Thread.currentThread().getName();
        for (int i = 0; i < 5; i++) {
            System.out.println(tName + "-" + name);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 同步代码块-类锁测试
     *
     * @param
     * @return void
     * @author dduan
     * @version 1.0
     * @date 2023/4/6
     */
    private void testSynchronizedCodelockClass() {
        MySynchronized m1 = new MySynchronized();
        MySynchronized m2 = new MySynchronized();
        Thread t1 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "启动");
            m1.synchronizedCodelockClass();
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t1.setName("甲线程");
        t1.start();

        Thread t2 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "启动");
            m2.synchronizedCodelockClass();
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t2.setName("乙线程");
        t2.start();
    }

    /**
     * 同步代码块-对象锁测试
     *
     * @param
     * @return void
     * @author dduan
     * @version 1.0
     * @date 2023/4/6
     */
    private void testSynchronizedCodelockObjct() {
        MySynchronized m1 = new MySynchronized();
        MySynchronized m2 = new MySynchronized();
        Thread t3 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "启动");
            m1.synchronizedCodelockObjct();
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t3.setName("丙线程");
        t3.start();

        Thread t4 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "启动");
            m2.synchronizedCodelockObjct();
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t4.setName("丁线程");
        t4.start();
    }

    /**
     * 同步静态方法-测试
     *
     * @param
     * @return void
     * @author dduan
     * @version 1.0
     * @date 2023/4/6
     */
    private void testSynchronizedStaticFun() {
        Thread t5 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "启动");
            MySynchronized.synchronizedStaticFun();
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t5.setName("静态方法线程1");
        t5.start();

        Thread t6 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "启动");
            MySynchronized.synchronizedStaticFun();
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t6.setName("静态方法线程2");
        t6.start();
    }

    /**
     * 同步普通方法-测试
     *
     * @param
     * @return void
     * @author dduan
     * @version 1.0
     * @date 2023/4/6
     */
    private void testSynchronizedFun() {
        MySynchronized m1 = new MySynchronized();
        MySynchronized m2 = new MySynchronized();
        Thread t7 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "启动");
            m1.synchronizedFun();
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t7.setName("同步普通方法1");
        t7.start();

        Thread t6 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "启动");
            m2.synchronizedFun();
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t6.setName("同步普通方法2");
        t6.start();
    }

    public static void main(String[] args) {
        MySynchronized m = new MySynchronized();
        // 同步代码块-类锁测试
        // m.testSynchronizedCodelockClass();
        // 同步代码块-对象锁测试
        // m.testSynchronizedCodelockObjct();

        // 同步静态方法-测试
        // m.testSynchronizedStaticFun();

        // 同步普通方法-测试
        m.testSynchronizedFun();
    }
}
